﻿using App.Chat.Contract;
using App.Chat.Models.MongoModels;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
using Zws.MongoDb;

namespace App.Chat.Hubs
{
    public abstract class AbsChatHub : Hub
    {
        protected readonly CurrentUser _currentUser;
        protected readonly MongoDbClientFacade _mongoDbClient;
        public AbsChatHub(IHttpContextAccessor contextAccessor,
            MongoDbClientFacade mongoDbClient)
        {
            //hub的scope和context的scope隔离了？
            if (contextAccessor.HttpContext != null &&
           contextAccessor.HttpContext.Items.TryGetValue(CommonConst.ContextItemUserKey, out var service))
            {
                _currentUser = (CurrentUser)service!;
            }
            _mongoDbClient = mongoDbClient;
        }
        public override async Task OnConnectedAsync()
        {
            //TODO 优化？
            await _mongoDbClient.DeleteAsync<OnlineUserConnect>(x => _currentUser.Id.Equals(x.UserId));
            await _mongoDbClient.InsertAsync<OnlineUserConnect>(new OnlineUserConnect
            {
                ConnectId = Context.ConnectionId,
                UserId = _currentUser.Id
            });
            //如果没有在mongo中查到未读消息存储，则创建
            if (!(await _mongoDbClient.IsExistAsync<UnReadAudit>(x => _currentUser.Id.Equals(x.UserId))))
                await _mongoDbClient.InsertAsync<UnReadAudit>(new UnReadAudit
                {
                    UserId = _currentUser.Id,
                    FriendAddSuccessTipCount = 0,
                    FriendAskAddTipCount = 0
                });
            await base.OnConnectedAsync();
        }
        public override async Task OnDisconnectedAsync(Exception? exception)
        {
            //因为是web，如果使用者刷新了connectid会发生变化，所以断连要删除旧的
            await _mongoDbClient.DeleteAsync<OnlineUserConnect>(x => Context.ConnectionId.Equals(x.ConnectId));
            await base.OnDisconnectedAsync(exception);
        }
        public async Task<string?> GetConnIdByUserIdAsync(string userId)
        {
            return (await _mongoDbClient.FindSingleAsync<OnlineUserConnect>(x => userId.Equals(x.UserId)))?.ConnectId;
        }
        public async Task<bool> IsOnlineByUserIdAsync(string userId)
        {
            return await _mongoDbClient.IsExistAsync<OnlineUserConnect>(x => userId.Equals(x.UserId));
        }
        public async Task<string?> GetCurrentSessionUserAsync(string userId)
        {
            return (await _mongoDbClient.FindSingleAsync<OnlineUserConnect>(x => userId.Equals(x.UserId)))?.SessionId;
        }
    }
}
